#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QThread>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();

    connect(ui->searchButton, &QPushButton::clicked, this, &MainWindow::searchSerial);
    connect(ui->openButton, &QPushButton::clicked, this, &MainWindow::openSerial);
    connect(ui->closeButton, &QPushButton::clicked, this, &MainWindow::closeSerial);
    connect(&serialPort, &QSerialPort::readyRead, this, &MainWindow::readMsg);
    // connect(&serialPort, SIGNAL(readyRead()), this, SLOT(readMsg()));
    connect(ui->sendLineEdit, &QLineEdit::returnPressed,this,[=]() {
        MainWindow::sendMsg();
        // ui->sendLineEdit->clear();
});
    connect(ui->clearButton, &QPushButton::clicked, this, &MainWindow::clearRecvMsg);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    // 首先将搜索按钮设为不可用状态
    ui->searchButton->setDisabled(true);

    // 获取可用的串口信息列表#include<QProcess>
    infoList = QSerialPortInfo::availablePorts();

    // 向串口设置组合框中添加可用的串口编号
    foreach (QSerialPortInfo info, infoList) {
        ui->serialComboBox->addItem(info.portName());
    }

    // 设置波特率、数据位、校验位、停止位以及流控制等
    serialPort.setBaudRate(QSerialPort::Baud115200);
    ui->baudrateComboBox->setCurrentIndex(ui->baudrateComboBox->findText(QString::number(serialPort.baudRate())));
    ui->databitsComboBox->setCurrentIndex(ui->databitsComboBox->findText(QString::number(serialPort.dataBits())));
    ui->parityComboBox->setCurrentIndex(ui->parityComboBox->findText(serialPort.parity() == QSerialPort::NoParity ? "None" :
                                                                         serialPort.parity() == QSerialPort::EvenParity ? "Even" :
                                                                         serialPort.parity() == QSerialPort::OddParity ? "Odd" :
                                                                         serialPort.parity() == QSerialPort::MarkParity ? "Mark" :
                                                                         "Space"));
    ui->stopbitsComboBox->setCurrentIndex(ui->stopbitsComboBox->findText(serialPort.stopBits() == QSerialPort::OneStop ? "1" :
                                                                             serialPort.stopBits() == QSerialPort::OneAndHalfStop ? "1.5" :
                                                                             serialPort.stopBits() == QSerialPort::TwoStop ? "2" :
                                                                             "1"));
    // ui->flowcontrolComboBox->setCurrentIndex(ui->flowcontrolComboBox->findText(serialPort.flowControl() == QSerialPort::NoFlowControl ? "None" :
    //                                                                                serialPort.flowControl() == QSerialPort::HardwareControl ? "Hardware" :
    //                                                                                serialPort.flowControl() == QSerialPort::SoftwareControl ? "Software" :
    //                                                                                "None"));
}

void MainWindow::searchSerial()
{
    // 清除上次搜索结果
    ui->serialComboBox->clear();

    // 获取可用的串口信息列表length
    infoList = QSerialPortInfo::availablePorts();

    // 向串口设置组合框中添加可用的串口编号
    foreach (QSerialPortInfo info, infoList) {
        ui->serialComboBox->addItem(info.portName());
    }
}

void MainWindow::openSerial()
{
    // 设置串口名称
    serialPort.setPortName(ui->serialComboBox->currentText());

    // 设置波特率、数据位、校验位、停止位以及流控制等
    serialPort.setBaudRate(ui->baudrateComboBox->currentText().toInt());
    serialPort.setDataBits(static_cast<QSerialPort::DataBits>(ui->databitsComboBox->currentText().toInt()));
    serialPort.setParity(static_cast<QSerialPort::Parity>(ui->parityComboBox->currentIndex()));
    serialPort.setStopBits(static_cast<QSerialPort::StopBits>(ui->stopbitsComboBox->currentIndex()));
    serialPort.setFlowControl(QSerialPort::NoFlowControl);
    // serialPort.setFlowControl(static_cast<QSerialPort::FlowControl>(ui->flowcontrolComboBox->currentIndex()));

    // 尝试打开串口
    if (serialPort.open(QIODevice::ReadWrite)) {
        ui->lb_status->setText("Open Serial Success.");
        ui->searchButton->setDisabled(true);
        ui->openButton->setDisabled(true);
        ui->closeButton->setEnabled(true);
    }
    else {
        ui->lb_status->setText("Open Serial Failed.");
    }
}

void MainWindow::closeSerial()
{
    // 关闭串口
    serialPort.clear();
    serialPort.close();

    ui->lb_status->setText("Close Serial Success.");
    ui->searchButton->setEnabled(true);
    ui->openButton->setEnabled(true);
    ui->closeButton->setDisabled(true);
}

void MainWindow::sendMsg()
{
    // 向串口发送数据
    QString msg = ui->sendLineEdit->text();

    // 断开readyRead事件
    // disconnect(&serialPort, &QSerialPort::readyRead, this, &MainWindow::readMsg);

    serialPort.write(msg.toUtf8());
    // serialPort.waitForBytesWritten();
    serialPort.waitForBytesWritten(50000);
    ui->receiveTextEdit->append("SEND(" + QString::number(msg.length()) + "): " + msg);
}

void MainWindow::readMsg()
{
    // 从串口接收数据
    // QByteArray msg = serialPort.readAll();

    // ui->receiveTextEdit->append("RECV(" + QString::number(msg.length()) + "): " + QString::fromLocal8Bit(msg));
    // ui->receiveTextEdit->append("RECV(" + QString::number(msg.length()) + "): " + QString::fromUtf8(msg));

    // connect(&serialPort, &QSerialPort::readyRead, this, &MainWindow::readMsg);

    //  for(int i = 0; i < 5; i++) {
    //     QThread::msleep(50);//阻塞延时50ms

    //     // 从串口接收数据
    //     QByteArray msg2 = serialPort.readAll();

    //     // ui->receiveTextEdit->append("RECV(" + QString::number(msg2.length()) + "): " + QString::fromLocal8Bit(msg2));
    //     ui->receiveTextEdit->append("RECV(" + QString::number(msg2.length()) + "): " + QString::fromUtf8(msg2));
    // }

    QByteArray data;
    const int nMax = 64 * 1024;
    QString m_dataCom;
    for(;;) {
        data = serialPort.readAll(); //读取串口数据
        if(data.isEmpty()){//没有读取到串口数据就退出循环
            qDebug() << "no more data";
            break;
        }
        //读取到的串口数据，加入到QByteArray m_dataCom
        m_dataCom.append(data);
        if(m_dataCom.size() > nMax){    //防止 m_dataCom 过长
            m_dataCom = m_dataCom.right(nMax);
        }
    }
    ui->receiveTextEdit->append("RECV(" + QString::number(m_dataCom.length()) + "): " + m_dataCom);
}

void MainWindow::clearRecvMsg()
{
    ui->receiveTextEdit->clear();
}
